package de.unistuttgart.iaas.interaction.mail;

import java.io.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;
import com.eaio.uuid.UUID;

import javax.mail.internet.*;
import javax.mail.*;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import com.sun.mail.imap.*;
import com.sun.mail.pop3.POP3Folder;


import de.unistuttgart.iaas.interaction.mail.database.MySQLAccess;
import de.unistuttgart.iaas.interaction.mail.services.AutoRun;
import de.unistuttgart.iaas.interaction.mail.services.GetRequest;
import de.unistuttgart.iaas.interaction.mail.util.CommonTools;
import de.unistuttgart.iaas.interaction.mail.util.ConfigFileHandler;
import de.unistuttgart.iaas.interaction.mail.util.LoggingFileHandler;

/**
 * The main function of this class is to receive every new mail in the admin-account.
 * And all mails will be input in the database.
 * @author Lina Sun
 *
 */
public class ReceiveMail
{
	private static String success = "Your request have been accepted and will be done.";
	private static String fail= "Sorry! Your request cann't be accepted.\n";
	private static String reason_dbconn= "Database Connection Error.\n";
	private static String reason_parameter = "Invalid inputparameter.\n";
	private static String reason_sql= "SQL Error.\n";
	private static String pop3 = "pop3"; 
	private static Logger logger = Logger.getLogger(ReceiveMail.class);

	/**
	 * This method is used to receive every new mail in the admin-account, gives every mail an unique identify,
	 * and set parameter mail_class as Notification, RESPONSE or REGISTER, UNKNOWN, mail_state as NEW.
	 *
	 * @throws MessagingException
	 */
	public static void ReceiveMail(String configurationData) throws MessagingException
	{

		ConfigFileHandler config = new ConfigFileHandler(configurationData);
		LoggingFileHandler logFileHandler = new LoggingFileHandler(configurationData);
		MySQLAccess dao = new MySQLAccess();
		Connection conn = null;
		
		
		Store store=null;
		Folder folder=null;
			    	
    	String recieveHost = config.getRecieveHost();
    	String username = config.getUsername();
    	String password = config.getPassword();  
		String mailAddress = config.getMailAddress();
		String temp = mailAddress.replace("@", "_");
		String table_mailids = temp.replace(".","_");
		DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
		String mail_message= "";
		Part mail_attachment = null;
		
		Properties properties = new Properties();
		properties.setProperty("log4j.rootLogger", logFileHandler.getMailLogLevel()+", R");
		properties.setProperty("log4j.appender.R", logFileHandler.getMailAppender());
		properties.setProperty("log4j.appender.R.File", logFileHandler.getReceiveMailLogFilePath());
		properties.setProperty("log4j.appender.R.MaxFileSize", logFileHandler.getMailLogFileSize() );
		properties.setProperty("log4j.appender.R.MaxBackupIndex", logFileHandler.getMailMaxBackupIndex());
		properties.setProperty("log4j.appender.R.layout", logFileHandler.getMailLayout());
		properties.setProperty("log4j.appender.R.layout.ConversionPattern", logFileHandler.getMailPattern());
		PropertyConfigurator.configure( properties );
		
		logger.info("----------------------ReceiveMailService-------------------------");
		
		try{
			
		conn = dao.connDataBase(config);
		
		Session session = AdminConnector.recieveConnector(config);
		
		if(conn!=null&&session!=null)
		{

		    	store = session.getStore("pop3");
		    	store.connect(recieveHost, username, password);	
				POP3Folder inbox = (POP3Folder) folder;

		    	folder = store.getDefaultFolder();
		    	if (folder == null) throw new Exception("No default folder");
		    	folder = folder.getFolder("INBOX");
		    	if (folder == null) throw new Exception("No POP3 INBOX");
		    	folder.open(Folder.READ_ONLY);
		    	Message[] msgs = folder.getMessages();
		    	Statement statement = conn.createStatement();
		    	

				for (int i = 0; i < msgs.length; i++) 
				{
					String uid = ((POP3Folder) folder).getUID(msgs[i]); 
					ResultSet rs = statement.executeQuery("select id from maildb."+ table_mailids +" where pop3_uid='"+uid+"'");

					if(!rs.next())
					{							
						Message oneMail = msgs[i];
						String mail_from=((InternetAddress)oneMail.getFrom()[0]).getAddress(); 
						String mail_to = config.getMailAddress(); 
						String mail_subject = oneMail.getSubject();
						String mail_class = CommonTools.mailClassIdentifier(conn, oneMail, config.getMailAddress(), config);
						String mail_from_username= ((InternetAddress)oneMail.getFrom()[0]).getPersonal();
						
						
						if(!mail_class.equals(""))
						{
							UUID u = new UUID();
							String mail_id=u.toString();
							String mail_receivedDate = df.format(oneMail.getSentDate());	
							String mail_state = "NEW";
							Part messagePart=oneMail;
							
							mail_message= CommonTools.getMessage(messagePart);
							System.out.println(mail_message);
							mail_attachment = CommonTools.getAttachment(messagePart);
							
							if(mail_attachment!=null)
							{
								String filename = mail_attachment.getFileName();
	    						InputStream fin = mail_attachment.getInputStream();
	    						PreparedStatement preStatementAtt = conn.prepareStatement("insert into maildb."+ config.getTable_mailattachments() +"(mail_id,filename,content) values(?,?,?)");
	   	 					 	preStatementAtt.setString(1, u.toString());
	   	 					 	preStatementAtt.setString(2, filename);
	   	 					 	preStatementAtt.setBlob(3, fin);
	   	 					 	preStatementAtt.executeUpdate();
	   	 					 	preStatementAtt.close();										
							}
							
//							Object content=messagePart.getContent();
//		    			
//							if (content instanceof Multipart)
//							{
//								Multipart mp = (Multipart)content;
//		    				    int counts = mp.getCount();	    
//								for(int k=0;k<mp.getCount();k++)
//								{
//									BodyPart bp = mp.getBodyPart(k);
//									String contenttype = bp.getContentType();
//									int nameindex = contenttype.indexOf("name");
//									boolean conname = false;
//									if(nameindex!=-1)
//									{
//										conname= true;
//									}
//									if(bp.isMimeType("text/plain") && !conname)
//									{
//		    					
//										mail_message=(String)CommonTools.getText(bp);			    					
//				    						System.out.println(mail_message);
//									}
//									if(t instanceof InputStream)
//									{
//			    						String filename = bp.getFileName();
//			    						System.out.println("3:"+ filename);
//			    						InputStream fin = bp.getInputStream();
//			    						PreparedStatement preStatementAtt = conn.prepareStatement("insert into maildb."+ config.getTable_mailattachments() +"(mail_id,filename,content) values(?,?,?)");
//			   	 					 	preStatementAtt.setString(1, u.toString());
//			   	 					 	preStatementAtt.setString(2, filename);
//			   	 					 	preStatementAtt.setBlob(3, fin);
//			   	 					 	preStatementAtt.executeUpdate();
//			   	 					 	preStatementAtt.close();			    						
//									}
//								}
//		        
//							}	else
//							{
//								mail_message=CommonTools.getText(messagePart);
//							}
				 			PreparedStatement preStatement = conn.prepareStatement("insert into maildb."+ config.getTable_mailbox() +" values(?,?,?,?,?,?,?,?,?,?)");
				 			String mail_replyid = "";
				 			
				 			if(mail_class.equalsIgnoreCase("RESPONSE"))
							{
								int index = mail_subject.indexOf("Mail-ID:");
								mail_replyid = mail_subject.substring(index+8);								
							}else if(mail_class.equalsIgnoreCase("NOTIFICATION"))
							{
								mail_from_username="Adminstrator";
							}
				 										
							preStatement.setString(1, u.toString());
				 			preStatement.setString(2, mail_replyid);
				 			preStatement.setString(3, mail_receivedDate);
				 			preStatement.setString(4, mail_from);
				 			preStatement.setString(5, mail_from_username);
				 			preStatement.setString(6, mail_to);
				 			preStatement.setString(7, mail_subject);
				 			preStatement.setString(8, mail_message);					 			
				 			preStatement.setString(9, mail_class);
							preStatement.setString(10, "NEW");
				 			preStatement.executeUpdate();
				 			preStatement.close();
				 			
				 			statement.executeUpdate("insert into maildb."+table_mailids+"(pop3_uid) values ('"+ uid+"')" );
				 			
				 			logger.info("Receive a new mail\n from: "+ mail_from+"\n to: "+ mail_to+"\n subject: "+ mail_subject+"\n");
				 			System.out.println("Receive a new mail\n from: "+ mail_from+"\n to: "+ mail_to+"\n subject: "+ mail_subject+"\n");
								
						}else{
							logger.info("unknown mailClass\n from: "+ mail_from+"\n to: "+ mail_to+"\n subject: "+ mail_subject+"\n");
							System.out.println("unknown mailClass\n from: "+ mail_from+"\n to: "+ mail_to+"\n subject: "+ mail_subject+"\n");
						}						
					}
				}
			}else if(session== null){
				//ErrorHandler
				logger.error("Mail session error in ReceiveMail.");
				System.out.println("session error!");
			}
		folder.close(true);
		store.close();
		}catch(Exception e)
		{
			store.close();
			e.printStackTrace();
		}
		
	}


}
